package view;

import java.awt.Component;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import model.Project;
import utils.RboxFileFilter;
import utils.weka.view.Messages;
import viewInterfaces.IViewProjectManagement;
import controller.ControllerProjectManagement;
import controllerInterfaces.IControllerProjectManagement;

/**
 *  
 * Presents user interface for take to actions over project such as Open, Save and Saves as it.
 * @see Project 
 *
 */
public class ViewProjectManagement implements IViewProjectManagement {

	/** MVC++ Controller
	* @see ControllerProjectManagement*/
	private IControllerProjectManagement myController;
    	

	/** The filechooser for loading and saving object files. */
    private JFileChooser m_FileChooser;

    /** Project Name Setup Dialog*/
	private JFrame dialog;

	/** Project Name Text Field */
	private JTextField textFieldNameProject;
	  

	/**
	 * Set the MVC++ Controller Class for this View.</br>
	 * ControllerProjectManagement is manipulable through {@link IControllerProjectManagement} interface
	 * @param	controller	MVC++ Controller
	 * @see	ControllerProjectManagement
	 * @see IControllerProjectManagement
	 */	    
	public void setController(IControllerProjectManagement controller) {
		this.myController = controller;		
	}

	
	/**
	 * Invoke a user interface for create a new project
	 * @see Project
	 */
	public void New() {
		dialog = new JFrame("New Rbox Project");
		dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		
		JPanel panelContent = new JPanel();
		dialog.getContentPane().add(panelContent);
		
		JLabel labelNameProject = new JLabel("Name project:");
		
		if(textFieldNameProject == null)
		{
			textFieldNameProject = new JTextField();
		}
		textFieldNameProject.setColumns(20);
		
		JButton btnOK = new JButton("OK");
		dialog.getRootPane().setDefaultButton(btnOK);
		btnOK.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				createProject();
			}
		});
		
		JButton btnCancel = new JButton("Cancel");
		btnCancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				dialog.dispose();
			}
		});
		
		panelContent.add(labelNameProject);
		panelContent.add(textFieldNameProject);
		panelContent.add(btnOK);
		panelContent.add(btnCancel);

		dialog.pack();
		dialog.setVisible(true);
		dialog.setLocationRelativeTo((Component) myController.getViewMain());

	}



	/**
	 * Invoke a user interface for load a existent project from file
	 * @see Project
	 */
	public Object Load() {
		if (m_FileChooser == null) {
			createFileChooser();
		}
		int returnVal = m_FileChooser.showOpenDialog((Component) myController.getViewMain());
		if (returnVal == JFileChooser.APPROVE_OPTION)
		{
			File selected = m_FileChooser.getSelectedFile();
			try
			{
				ObjectInputStream oi = new ObjectInputStream(new BufferedInputStream(new FileInputStream(selected)));
				myController.SetSelectedFile(m_FileChooser.getSelectedFile());
				Object obj = oi.readObject();
				oi.close();
				
				return obj;
			}
			catch (Exception ex)
			{
				JOptionPane.showMessageDialog(
						(Component) myController.getViewMain(),
						Messages.getInstance().getString("GenericObjectEditor_OpenObject_Exception_JOptionPaneShowMessageDialog_Text")
						+ selected.getName() 
						+ Messages.getInstance().getString("GenericObjectEditor_OpenObject_Exception_JOptionPaneShowMessageDialog_Text") + ex.getMessage(),
						Messages.getInstance().getString("GenericObjectEditor_OpenObject_Exception_JOptionPaneShowMessageDialog_Text"),
						JOptionPane.ERROR_MESSAGE);
			}
		}
		
		return null;
	}

    /**
     * Creates the file chooser the user will use to save file of {@link Project}.
     * @param object project object to save
     * @return operation status
     * @return status of saved operation. True for valid operation, otherwise, invalid operation.     * 
     * @see Project
     */	
	public boolean Save(Object object) {
		boolean isOperationOK = false;
		
		if (m_FileChooser == null) {
			createFileChooser();
		}
		int returnVal = m_FileChooser.showSaveDialog((Component) myController.getViewMain());
		
		if (returnVal == JFileChooser.APPROVE_OPTION)
		{
			File sFile = m_FileChooser.getSelectedFile();
			String newName = sFile.getPath() + ".rbox";
			File sFile2 = new File(newName);
			
			if (SaveInFile(object, sFile2))
			{
				myController.SetSelectedFile(sFile2);
				isOperationOK = true;
			}
		}
		
		return isOperationOK;

	}
	
	
	
    /**
     * Save {@link Project} current file.
     * @param object current project object.
     * @param sFile	project file.
     * @return status of saved operation. True for valid operation, otherwise, invalid operation.
     * @see Project
     */	
	public boolean Save(Object project, File sFile) {
		
		return SaveInFile(project, sFile);
	}	
	
	
	
	/**
	 * Save object in a file.
	 * @param object object to save in file
	 * @param file	file of object
     * @return status of saved operation. True for valid operation, otherwise, invalid operation.
	 */
	private boolean SaveInFile(Object object, File file)
	{
		try
		{
			ObjectOutputStream oo = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
			oo.writeObject(object);
			oo.close();
			return true;
		}
		catch (Exception ex)
		{
			javax.swing.JOptionPane.showMessageDialog((Component) myController.getViewMain(), ex.getMessage(), "File Error",javax.swing.JOptionPane.ERROR_MESSAGE);
		}
		return false;
	}
	
	
    /**
     * Present the file chooser the user will use to save/load files with.
     */
    private void createFileChooser() {
      m_FileChooser = new JFileChooser(new File(System.getProperty("user.dir")));
      m_FileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
      m_FileChooser.setFileFilter(new RboxFileFilter());
    }
    
    
    /**
     * Set a text field of project name.</br>
	 * This method is only used for realize unit testing.
     * @param name project name
     */
    public void setProjectNameText(String name)
    {
    	if (textFieldNameProject == null)
    	{
    		textFieldNameProject = new JTextField();
    	}
    	
		textFieldNameProject.setText(name);
    }
    
    
    /**
	 * Create a new project.
	 */
    public void createProject() {
		if(!textFieldNameProject.getText().isEmpty())
		{
			myController.createProject(textFieldNameProject.getText());
			dialog.dispose();
		}
		else
		{
			renderError(utils.Codes.errorProjectName, utils.Messages.errorProjectName);
		}
	}


	/**
	 * Show error dialog.
	 * @param code	error code.
	 * @param message	error message.
	 */	
	private void renderError(int code, String message) {
		javax.swing.JOptionPane.showMessageDialog(this.dialog, code + " - " + message, "Error",javax.swing.JOptionPane.ERROR_MESSAGE);
	}


	
	/**
	 * Get file chooser.</br>
	 * This method is only used for realize unit testing.
	 * @return file chooser
	 */
	public JFileChooser getFileChooser()
	{
		return this.m_FileChooser;
	}
	
	
}

